// 引入fs模块
const fs = require('fs');
// 引入path模块
const path = require('path');
// 引入crypto加密模块
// const crypto = require('crypto');
// 引入mysql模块 相对路径
const sql = require('../model/config');
// 引入自定义加密模块
const { encrypt, decrypt } = require('../until/crypto-createCipheriv');

// 注册请求中间件
exports.register = async function (req,res,next) {
    // 获取前端传递的数据  req.body { username:'zhangsan',password:'123'}
    // const username = req.body.username;
    // const password = req.body.password;
    // 精简，使用ES6,对象的解构赋值
    const { username,password,nickname } = req.body;  
    // const secret = 'abcdefg';
    // const hash = createHmac('sha256', secret)
    //             .update('I love cupcakes')
    //             .digest('hex');
    // console.log(hash);

    // 注册去重
    const result = await sql(`select * from user`);  // [{},{}]
    // 判断是否数据库中有相同的用户名
    const isUserName = result.some(item=>item.username === username);
    // 判断
    if (isUserName) {
        res.send({
            code:500,
            msg:"此用户名已存在，请前去登录！"
        }); 
        return;
    }
    
    // 对称和非对称加密

    // 1.防内: 系统管理员看到用户的密码，做一些XXXX的事情
    // 2.防外：防止黑客获取用户的密码，做一些XXXXX的事情

    // 定义密钥
    // var secret = 'hellom';
    // var newPassword = crypto
    //     .createHmac('sha256',secret)
    //     .update(password,'utf-8')
    //     .digest('hex');
    
    /**
     *  MD5：128位
        SHA-1：160位
        SHA256 ：256位
        SHA512：512位
     */
    // console.log(username,password);
    // 精简，使用ES7, async / await
    // try / catch   捕获js的错误，，好处是它不会影响后面代码的执行
    // var data = await sql(`INSERT INTO user value(NULL,${username},"${password}")`);
    console.log('注册密码: ',password);
    console.log("==========注册===========");
    console.log('注册密码加密: ',encrypt(password));
    try {
        await sql(`INSERT INTO user value(NULL,"${username}","${nickname}","${encrypt(password)}","img/user.png",0)`);
        res.send({
            code:200,
            msg:"注册成功"
        });         
    } catch (error) {
        next(error);       
    } 
}

// 登录请求中间件
exports.login = async function (req,res) {
    // 获取前端传递的登录信息
    const username = req.body.username;
    const password = req.body.password;
    const users  = await sql(`select * from user where username = "${username}"`); // [{}]

    // 定义密钥  加密
    // var secret = 'hellom';
    // var newPassword = crypto
    //     .createHmac('sha256',secret)
    //     .update(password,'utf-8')
    //     .digest('hex');

    if (users.length === 0) {
        res.send({
            code:500,
            msg:"登录失败,请前去注册！"
        });
    }else{
        console.log("==========登录===========");
        console.log("登录密码解密: ",decrypt(users[0].password));
        if ( decrypt(users[0].password) === password ) {
            // 设置cookie
            res.cookie('username',users[0].username);

            // 做重复登录验证
            if (users[0].login === 1) {
                res.send({
                    code:500,
                    msg:"您已登录,请不要重复登录,点击'确定',强制登录,点击'取消',不登录"
                })
            } else {
                // 在服务端保存用户的登录信息 -- 登录用户验证
                req.session.user = users[0]; // [{username:'zhangsan',password:'123',nickname:'发哥',avatar：'img/user.png',login:1}]
                // 更新登录状态
                await sql(`update user set login = 1 where username = "${username}"`); 
                // 响应前端
                res.send({
                    code:200,
                    msg:"登录成功",
                    user:{ username:users[0].username,nickname:users[0].nickname }
                });
            }            
        }else{
            res.send({
                code:500,
                msg:"密码错误"
            });
        }         
    }
}

// 清除登录用户信息请求中间件
exports.quit = (req,res)=>{
    console.log('quit=========',req.body);
    req.session.destroy(async () => {      
        // 更改用户登录状态
        await sql(`update user set login = 0 where nickname = "${req.body.nickname}" or username = "${req.body.username}" `);  
        res.send({
            code:200,
            msg:"用户session清除成功！"
        });
    });
}

// 文件上传路由 upload.single('avatar') avatar 对应的是前端 input类型为file的name值
exports.uploads = async (req,res)=>{
    const { hiddenUsername, nickname, oldPassword, newPassword } = req.body;
    // 定义全局弹窗变量
    let alert = '';
    // 1.判断是否有图片上传
    if (req.file) {
        // console.log(req.file);
        // {
        //     fieldname: 'avatar',
        //     originalname: 'allviphrefrtgif.gif',
        //     encoding: '7bit',
        //     mimetype: 'image/gif',
        //     destination: 'C:\\Users\\Web\\Desktop\\Hellom\\public\\img\\',
        //     filename: 'fe08cbeb4727945cbbda8408508ea322',
        //     path: 'C:\\Users\\Web\\Desktop\\Hellom\\public\\img\\fe08cbeb4727945cbbda8408508ea322',
        //     size: 122590
        // }
        //判断文件类型
        const fileName = req.file.originalname.toLowerCase();
        const fileSize = req.file.size;
        const name = fileName.substr(fileName.lastIndexOf('.')+1,fileName.length);
        if (!/(gif|jpg|jpeg|png|bmp|webp)$/.test(name) || fileSize >= 1048576 ) {
            alert +=  "图片类型必须是.gif,jpeg,jpg,png,bmp,webp中的一种,且图片大小不能大于1M！";
        } else {
            const oldPath = req.file.path;
            // 不会去重
            // var newPath = req.file.path + path.extname(req.file.originalname);
            // 会去重，不能上传相同名称的图片
            const newPath = req.file.destination + req.file.originalname;
            // 上传图片重命名
            fs.renameSync(oldPath,newPath);
            // 把图片的服务端的请求路径存储到数据库中
            const imgSrc = 'img/'+ req.file.originalname;
            await sql(`update user set avatar = "${imgSrc}" where username = "${req.body.hiddenUsername}"`);  
            alert +=  "头像修改成功";   
        }
    }

    // 2.判断用户是否修改昵称
    if (nickname) {
        await sql(`update user set nickname = "${nickname}" where username = "${hiddenUsername}"`);
        alert +=  " 昵称修改成功 ";
    }

    // 3.判断用户是否修改密码
    if (oldPassword && newPassword) {
        const password = await sql(`select password from user where username = "${hiddenUsername}"`);
        if (oldPassword === input(password[0].password)) {
            await sql(`update user set password = "${output(newPassword)}" where username = "${hiddenUsername}"`);            
            alert +=  " 密码修改成功 ";
        }else{
            alert +=  " 旧密码输入错误 ";
        }
    }

    res.send(`<script>alert("${alert}");location.href="/"</script>`);
}


